package com.yoyo.schedule.zookeeper;

import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.KeeperState;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
public class ZooKeeperWatcher implements Watcher {
    @Setter
    @Getter
    private Map<String, Watcher> pathToWatcherMap = new ConcurrentHashMap<String, Watcher>();
    @Setter
    @Getter
    private ZooKeeperManager zooKeeperManager;

    public ZooKeeperWatcher(ZooKeeperManager zooKeeperManager) {
        this.zooKeeperManager = zooKeeperManager;
    }

    public void registerChildrenChanged(String path, Watcher watcher) throws Exception {
        zooKeeperManager.getZooKeeper().getChildren(path, true);
        pathToWatcherMap.put(path, watcher);
    }

    public void process(WatchedEvent watchedEvent) {
        if (watchedEvent.getType() == Event.EventType.NodeChildrenChanged) {
            String path = watchedEvent.getPath();
            Watcher watcher = pathToWatcherMap.get(path);
            if (watcher != null) {
                try {
                    watcher.process(watchedEvent);
                } finally {
                    try {
                        if (zooKeeperManager.getZooKeeper().exists(path, null) != null) {
                            zooKeeperManager.getZooKeeper().getChildren(path, true);
                        }
                    } catch (Exception e) {
                        log.error(path + ":" + e.getMessage(), e);
                    }
                }
            } else {
                log.info("" + watchedEvent.getType() + ":" + watchedEvent.getState() + "" + watchedEvent.getPath());
            }
        } else if (watchedEvent.getState() == KeeperState.AuthFailed) {
            log.info("tb_hj_schedule zookeeper $status =KeeperState.AuthFailed");
        } else if (watchedEvent.getState() == KeeperState.ConnectedReadOnly) {
            log.info("tb_hj_schedule zookeeper $status =KeeperState.ConnectedReadOnly");
        } else if (watchedEvent.getState() == KeeperState.Disconnected) {
            log.info("tb_hj_schedule zookeeper $status =KeeperState.Disconnected");
            try {
                zooKeeperManager.reConnect();
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        } else if (watchedEvent.getState() == KeeperState.NoSyncConnected) {
            log.info("tb_hj_schedule zookeeper $status =KeeperState.NoSyncConnected ");
            try {
                zooKeeperManager.reConnect();
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        } else if (watchedEvent.getState() == KeeperState.SaslAuthenticated) {
            log.info("tb_hj_schedule zookeeper $status =KeeperState.SaslAuthenticated");
        } else if (watchedEvent.getState() == KeeperState.Unknown) {
            log.info("tb_hj_schedule zookeeper $status =KeeperState.Unknown");
        } else if (watchedEvent.getState() == KeeperState.SyncConnected) {
            log.info("");
        } else if (watchedEvent.getState() == KeeperState.Expired) {
            log.error("...");
            try {
                zooKeeperManager.reConnect();
            } catch (Exception e) {
                log.error(e.getMessage(), e);
            }
        }
    }
}